#include "modbus_host_uart.h"
#include "stm32_uart.h"
#include "cmsis_os2.h"
#include "app_netxduo.h"


/********************************** define **************************************/
static int32_t host_init(void *handle);
static int32_t host_read_input_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t host_read_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t host_write_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t host_send_data_rtu(void *com_handle, uint8_t *data, uint16_t length);
static int32_t host_send_data_tcp(void *com_handle, uint8_t *data, uint16_t length);
static int32_t host_delay(void *handle, uint32_t ms);


static MODBUS_Data_Buffer_t tx_buffer_rtu = 
{
  UART7_Transfer.TxData,
  &UART7_Transfer.RxData_Len,
  (int32_t *)&UART7_Transfer.Transfer_TX_Status,
};

static MODBUS_Data_Buffer_t rx_buffer_rtu = 
{
  UART7_Transfer.RxData,
  &UART7_Transfer.RxData_Len,
  (int32_t *)&UART7_Transfer.Transfer_RX_Status,
};

static MODBUS_Data_Buffer_t tx_buffer_tcp = 
{
  nx_tx_data.data,
  (uint16_t *)&nx_tx_data.length,
  (int32_t *)&nx_tx_data.status,
};

static MODBUS_Data_Buffer_t rx_buffer_tcp = 
{
  nx_rx_data.data,
  (uint16_t *)&nx_rx_data.length,
  (int32_t *)&nx_rx_data.status,
};

static MODBUS_Reg_Count_t input_reg;
static MODBUS_Reg_Count_t hold_reg;

static uint16_t socket_reg_start_addr = 0x0000;
static uint16_t socket_reg_count = 0x0080;

static uint8_t device_id = 0x01;
static uint32_t timeout = 200;

uint8_t modbus_host_buff[256];

MODBUS_User_Reg_t modbus_host_uart = 
{
  &modbus_host_uart,
  host_init,
};

static int32_t host_init(void *handle)
{
  MODBUS_User_Reg_t *host_handle = (MODBUS_User_Reg_t *)handle;
  
  host_handle->modbus_delay = host_delay;
  host_handle->read_input_reg = host_read_input_reg;
  host_handle->read_hold_reg = host_read_hold_reg;
  host_handle->write_hold_reg = host_write_hold_reg;
  
  host_handle->send_rtu = host_send_data_rtu;
  host_handle->send_rtu_com = &huart7;
  host_handle->tx_buffer_rtu = &tx_buffer_rtu;
  host_handle->rx_buffer_rtu = &rx_buffer_rtu;
  
  host_handle->send_tcp = host_send_data_tcp;
  host_handle->send_tcp_com = &huart7;
  host_handle->tx_buffer_tcp = &tx_buffer_tcp;
  host_handle->rx_buffer_tcp = &rx_buffer_tcp;
  
  host_handle->modbus_device_id = &device_id;
  host_handle->modbus_timeout = &timeout;
  
  input_reg.start_addr = &socket_reg_start_addr;
  input_reg.count = &socket_reg_count;
  hold_reg.start_addr = &socket_reg_start_addr;
  hold_reg.count = &socket_reg_count;
  host_handle->input_reg = &input_reg;
  host_handle->hold_reg = &hold_reg;
  
  return 0;
}

static int32_t host_delay(void *handle, uint32_t ms)
{
  osDelay(ms);
  return 0;
}

static int32_t host_send_data_rtu(void *com_handle, uint8_t *data, uint16_t length)
{
  uint32_t ret;
  HAL_GPIO_WritePin(UART7_DE_GPIO_Port, UART7_DE_Pin, GPIO_PIN_SET);
  ret = STM32_UART_TransmitData_DMA(com_handle, data, length);
//  HAL_GPIO_WritePin(UART7_DE_GPIO_Port, UART7_DE_Pin, GPIO_PIN_RESET);
  return ret;
}

static int32_t host_send_data_tcp(void *com_handle, uint8_t *data, uint16_t length)
{
  int32_t ret;
  
  ret = nx_packet_allocate(&NxAppPool, &nx_tx_data.packet, NX_TCP_PACKET, NX_NO_WAIT);
        
  ret = nx_packet_data_append(nx_tx_data.packet, (VOID *)data, length, &NxAppPool, NX_NO_WAIT);

  ret = nx_tcp_socket_send(com_handle, nx_tx_data.packet, NX_NO_WAIT);
  
  return ret;
}


static int32_t host_read_input_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  memcpy(&modbus_host_buff[reg_addr * 2], reg_data, reg_count * 2);
//  LPUART1_Transfer.TxData_Len = reg_count * 2;
//  memcpy(LPUART1_Transfer.RxData, reg_data, LPUART1_Transfer.TxData_Len);
//  STM32_UART_TransmitData(&hlpuart1, LPUART1_Transfer.RxData, LPUART1_Transfer.TxData_Len);
  return 0;
}


static int32_t host_read_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  memcpy(&modbus_host_buff[reg_addr * 2], reg_data, reg_count * 2);
//  LPUART1_Transfer.TxData_Len = reg_count * 2;
//  memcpy(LPUART1_Transfer.RxData, reg_data, LPUART1_Transfer.TxData_Len);
//  STM32_UART_TransmitData(&hlpuart1, LPUART1_Transfer.RxData, LPUART1_Transfer.TxData_Len);
  return 0;
}


static int32_t host_write_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  return 0;
}


